/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用木兰宽松许可证第2版]
 * 
 * https://zhiqim.org/project/zhiqim_components/zhiqim_upload_large.htm
 *
 * Zhiqim UploadLarge is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
+(function(Z)
{
//BEGIN

Z.UploadLarge = Z.Class.newInstance();
Z.UploadLarge.v = "1.6.0";
Z.UploadLarge.M = 1024 * 1024;
Z.UploadLarge.CHUNK_SIZE = 1024 * 500;

/****************************************/
//定义Z.UploadLarge下的原型属性和方法
/****************************************/
Z.UploadLarge.prototype =
{
    defaults:
    {
        //公共参数
        loading: null,
        elem: null,
        onSelected: null,
        onCompleted: null,         // 上传结束回调方法：单文件参数（fileId, fileName, fileUrl）；多文件参数（fileList, uploadedList）
        onCompletedForEach: null,  // 多文件上传，每个文件上传完成后的回调
        contextPath: null,
        showResult: true,
        fileMd5Target: 0,
        fileCopy: false,
        maxSizeMiB: 0,
        maxLoadingMiB: 5,
        runState: 0,               //上传状态：0：未开始，1：上传中，2：上传完成
        displayType: 0,            //展示样式：0：老版本，1：精简版，2：弹出浮框模式
        reConnectTimes: 3,         //上传过程中，失败的时候，尝试重连次数
        headerList: '',            //header设置列表
        
        //多选标识
        multiSelect: false,        //是否开启多选
        maxFileNum: 0,             //多文件上传数量限制
        dropWrap: null,            //展示列表容器
        multiPopup: false,         //是否用弹出框模式进行多文件上传
        multiDisplayType: 0,       //展示列表样式：0：列表样式，1：图文块模式
        doFileDelete: null,        //删除已上传文件：参数（fileId, fileName, fileUrl）
    },

    execute: function()
    {
        if (!this.multiSelect && !this.elem)
            return Z.alert('[Z.UploadLarge]单文件上传，[elem]参数需定义');
        if (this.multiSelect && !this.elem && !this.dropWrap)
            return Z.alert('[Z.UploadLarge]多文件上传，[elem][dropWrap]至少需定义一个');

        if (this.elem)
            this.$elem = Z.$elem(this.elem, "Z.UploadLarge");
        if (this.multiSelect && this.dropWrap) {
            this.$dropWrap = Z.$elem(this.dropWrap, "Z.UploadLarge");
        }

        if (typeof this.doFileDelete === 'function')
            this.deleteFile = true;
        this.random = Z.random(10);


        //列表容器存在
        if (this.$dropWrap)
        {
            if (!this.$elem)
                this.$elem = this.$dropWrap;
            else
                this.$dropWrap.on('click', this.addFileClick, this);
        }

        //使用HTML5上传组件，需要zhiqim_md5.js支持
        var accept = (!!this.fileFormatExt)?this.fileFormatExt:"*.*";
        this.$file = Z("<input id='Z_UploadLarge_upload_file_"+this.random+"' type='file' accept='"+accept+"' class='z-hide' " + (this.multiSelect?'multiple':'single') + ">");
        this.$file.appendToPos(this.$elem.parent())
            .on('change', this.onFileInputChange, this);
        this.$elem.on('click', this.addFileClick, this);

        //初始化进度容器
        var div = '';
        if (this.multiSelect)
        {// 多文件上传，进度列表容器
            this.fileIndex = 0;
            this.fileBufferIndex = 0;
            this.fileList = [];
            this.fileResults = [];
            this.uploadedList = [];

            if (!this.dropWrap){
                div = '<div id="Z_UploadLarge_dropWrap_'+this.random+'" class="z-pd5 z-mg-t10 z-mg-b10" style="display: none;">';
                div += '</div>';
                this.$dropWrap = Z(div).insertBefore(this.$elem);
                this.$dropWrap.on('click', this.addFileClick, this);
            }
            this.$dropWrap.on('mouseenter', this.dropWrapEnter, this)
                .on('mouseleave', this.dropWrapLeave, this)
                .on('dragover dragenter', Z.E.forbidden)
                .on('drop', this.dropWrapDrop, this);
            return;
        }
        // 常规的大文件上传，进度容器
        var left = this.$elem.offsetLeft();
        var top = this.$elem.offsetTop();
        var width = this.$elem.offsetWidth();
        var height = this.$elem.offsetHeight();
        switch (this.displayType)
        {
            case 0:
                div = '<div id="Z_UploadLarge_progress_'+this.random+'" style="position:absolute;display:none">';
                div += '    <div class="z-absolute z-ico z-file" style="top:0;left:0;width:32px;height:36px;"></div>';
                div += '    <div class="z-absolute z-px12" style="top:0;left:38px;width:310px;height:20px;line-height:20px;"><span id="Z_UploadLarge_fileName_'+this.random+'">文件名</span><span style="color:gray;font-weight:700">（<span id="Z_UploadLarge_all_'+this.random+'">0</span>M）</span></div>';
                div += '    <div class="z-absolute z-bg-gray" style="top:24px;left:38px;width:310px;height:10px;"><div style="width:0%;background-color:#ff6600;height:10px;" id="Z_UploadLarge_percent_'+this.random+'"></div></div>';
                div += '    <div class="z-absolute z-pointer z-round z-red z-font z-error z-px12" style="top:22px;left:358px;width:16px;height:16px;" id="Z_UploadLarge_cancel_'+this.random+'"></div>';
                div += '    <div class="z-absolute z-px12" style="top:36px;left:38px;width:98px;color:gray;">已上传：<span id="Z_UploadLarge_already_'+this.random+'">0</span>M</div>';
                div += '    <div class="z-absolute z-px12" style="top:36px;left:138px;width:98px;color:gray;">速度：<span id="Z_UploadLarge_speed_'+this.random+'">0K/s</span></div>';
                div += '    <div class="z-absolute z-px12" style="top:36px;left:238px;width:150px;color:gray;">剩余时间：<span id="Z_UploadLarge_remain_'+this.random+'">0秒</span></div>';
                div += '</div>';

                this.$progress = Z(div).appendTo(this.$elem.parent()).css({position: "absolute", top: top, left: left});
                this.$cancel = Z("#Z_UploadLarge_cancel_"+this.random);
                this.$cancel.click(this.cancel, this);

                div = '';
                div += '<div id="Z_UploadLarge_result_'+this.random+'" style="position:absolute;display:none">';
                div += '    <div class="z-absolute z-ico z-file" style="top:0;left:0;width:32px;height:36px;"></div>';
                div += '    <div class="z-absolute z-px12 z-round z-green z-ico z-success" style="top:1px;left:38px;width:16px;height:16px;"></div>';
                div += '    <div class="z-absolute z-px12" style="top:2px;left:56px;width:98px;color:green;">上传成功</div>';
                div += '    <div class="z-absolute z-px12" style="top:20px;left:38px;width:310px;height:20px;line-height:20px;"><span id="Z_UploadLarge_result_fileName_'+this.random+'">文件名</span>&nbsp;&nbsp;<a id="Z_UploadLarge_delete_'+this.random+'" style="cursor:pointer;color:green;">返回</a></div>';
                div += '</div>';

                this.$result = Z(div).appendTo(this.$elem.parent()).css({position: "absolute", top: top, left: left});
                this.$delete = Z("#Z_UploadLarge_delete_"+this.random);
                this.$delete.click(this.cancel, this);
                break;
            case 1:
                div = '<div id="Z_UploadLarge_progress_'+this.random+'" class="z-bd z-event-none" style="position:absolute;display:none">';
                div += '    <div class="Z-UploadLarge-progress-range z-absolute z-l0 z-t0 z-w100p z-h100p" style="background-color:#28a3ef;"></div>';
                div += '    <div class="Z-UploadLarge-progress-text z-absolute z-l0 z-t0 z-w100p z-h100p z-text-center" style="line-height:'+ height +'px;color:#777777;"></div>';
                div += '</div>';
                this.$progress = Z(div).appendTo(this.$elem.parent()).css(
                    {
                        position: "absolute",
                        top: top, left: left, width: width, height: height,
                        borderTopLeftRadius: this.$elem.css('border-top-left-radius'),
                        borderTopRightRadius: this.$elem.css('border-top-right-radius'),
                        borderBottomLeftRadius: this.$elem.css('border-bottom-left-radius'),
                        borderBottomRightRadius: this.$elem.css('border-bottom-right-radius'),
                        backgroundColor: '#FFFFFF',
                    });
                this.$progressRange = this.$progress.find('.Z-UploadLarge-progress-range');
                this.$progressText = this.$progress.find('.Z-UploadLarge-progress-text');
                break;
            case 2:
                this.$progressWrap = Z('#Z_UploadLarge_progress_wrap');
                if (!this.$progressWrap[0])
                {
                    this.$progressWrap = Z('<div id="Z_UploadLarge_progress_wrap" class="z-w100p z-h120 z-fixed" style="bottom:-120px;transition:bottom 0s;z-index:99999;">\n' +
                        '    <div class="ZULPW-content z-w400" style="margin:auto;">\n' +
                        '        <div class="ZULPW-title z-h40 z-lh40 z-relative" style="padding:0 15px;background-color:#f1f1f1;box-shadow:0 2px 5px 0 rgba(0,0,0,0.1);z-index:10;">\n' +
                        '            <span class="ZULPW-text">正在加载</span>\n' +
                        '            <i class="ZULPW-close z-font z-error z-absolute z-w16 z-h16 z-px16 z-pointer" style="line-height:1;transition:transform 200ms;right:15px;top:12px;"></i>\n' +
                        '        </div>\n' +
                        '        <ul class="ZULPW-list z-relative" style="padding:10px 15px;background:#fcfcfc;">' +
                        '               <li class="ZULPW-loading z-w100p z-h70 z-px16 z-l0 z-t0 z-text-center" style="padding:0 15px;line-height:60px;z-index:9;background:#fcfcfc;">文件读取中···</li>\n' +
                        '        </ul>\n' +
                        '    </div>\n' +
                        '</div>');
                    this.$progressWrap.appendTo(Z('body'));
                    this.$progressWrap.find('.ZULPW-close').on('mouseenter', function()
                    {
                        Z(this).attr('data-color', Z(this).css('color'));
                        Z(this).css({'transform': 'rotate(90deg)', 'color': '#fe4615'});
                    }).on('mouseleave', function()
                    {
                        var color = Z(this).attr('data-color');
                        Z(this).css({'transform': 'rotate(0deg)', 'color': color});
                    }).on('click', this.progressDialogHide, this);
                }
                this.$progressTitle = this.$progressWrap.find('.ZULPW-text');
                this.$progressLoading = this.$progressWrap.find('.ZULPW-loading');
                this.$progressList = this.$progressWrap.find('.ZULPW-list');
                this.$progressClose = this.$progressWrap.find('.ZULPW-close');

                div = '<li id="Z_UploadLarge_progress_'+this.random+'" class="ZULPW-item z-relative z-h70 z-pd-tb10" style="display:none;">\n' +
                    '    <div class="ZULPW-preview z-absolute z-w50 z-h50 z-t0" style="top:10px;border:1px solid #ccc;">\n' +
                    '        <div class="z-bg-white z-text-center" style="width:48px;height:48px;display:table-cell;vertical-align:middle;">\n' +
                    '            <img class="" src=""/>\n' +
                    '            <span class="z-px16 z-bold"></span>\n' +
                    '        </div>\n' +
                    '    </div>\n' +
                    '    <div class="ZULPW-detailInfo z-absolute z-px12" style="width:315px;height:20px;top:0;left:55px;line-height:20px;">\n' +
                    '        <span class="ZULPW-name z-text-ellipsis" style="vertical-align:top;max-width:200px;">文件名</span>\n' +
                    '        <span class="z-bold z-show-ib" style="vertical-align:top;color:gray;">（<span class="ZULPW-size">0</span>M）</span>\n' +
                    '    </div>\n' +
                    '    <div class="ZULPW-rangeInfo z-absolute" style="width:315px;top:22px;left:55px;">\n' +
                    '        <div class="z-absolute z-bg-gray" style="top:0;left:0;width:290px;height:10px;"><div class="ZULPW-range" style="width:0%;background-color:#28a3ef;height:10px;"></div></div>\n' +
                    '        <div class="ZULPW-cancel z-absolute z-pointer z-round z-red z-font z-error z-px12" style="top:-4px;right:0;width:16px;height:16px;"></div>\n' +
                    '    </div>\n' +
                    '    <div class="ZULPW-uploadInfo z-absolute" style="width:315px;top:36px;left:55px;">\n' +
                    '        <div class="z-absolute z-w90 z-px12" style="top:0;left:0;color:gray;"><i class="z-font z-px14 z-upload z-mg-r5"></i><span class="ZULPW-uploaded"></span>M</div>\n' +
                    '        <div class="z-absolute z-w90 z-px12" style="top:0;left:95px;color:gray;"><i class="z-font z-px14 z-graph z-mg-r5"></i><span class="ZULPW-speed"></span></div>\n' +
                    '        <div class="z-absolute z-px12" style="top:0;left:190px;width:125px;color:gray;"><i class="z-font z-px14 z-refresh z-mg-r5"></i><span class="ZULPW-time"></span></div>\n' +
                    '    </div>\n'+
                    '</li>';
                this.$progress = Z(div).appendTo(this.$progressList);
                this.$ZULPW_preview = this.$progress.find('.ZULPW-preview');
                this.$ZULPW_viewImg = this.$ZULPW_preview.find('img');
                this.$ZULPW_viewType = this.$ZULPW_preview.find('span');

                this.$ZULPW_detailInfo = this.$progress.find('.ZULPW-detailInfo');
                this.$ZULPW_name = this.$progress.find('.ZULPW-name');
                this.$ZULPW_size = this.$progress.find('.ZULPW-size');

                this.$ZULPW_rangeInfo = this.$progress.find('.ZULPW-rangeInfo');
                this.$ZULPW_range = this.$progress.find('.ZULPW-range');
                this.$ZULPW_cancel = this.$progress.find('.ZULPW-cancel');

                this.$ZULPW_uploadInfo = this.$progress.find('.ZULPW-uploadInfo');
                this.$ZULPW_uploaded = this.$progress.find('.ZULPW-uploaded');
                this.$ZULPW_speed = this.$progress.find('.ZULPW-speed');
                this.$ZULPW_time = this.$progress.find('.ZULPW-time');

                this.$ZULPW_cancel.on('click', function()
                {
                    this.clear();
                    this.progressDialogHide();
                }, this);
                break;
        }
    },

    addFileClick: function(event)
    {
        Z.E.forbidden(event);
        if (this.runState === 1){
            (top.Z || Z).failure("正在上传，请稍后...");
        }else if (Z.ua.indexOf("aliapp(qn") !== -1){
            (top.Z || Z).failure("千牛浏览器不支持上传，请选择其他浏览器打开");
        }else{
            this.$file[0].value = null;
            this.$file[0].click();
        }
    },

    dropWrapEnter: function(event)
    {//鼠标进入展示区
        Z.E.forbidden(event);
        var $wrap = Z(Z.E.target(event));
        $wrap.css('box-shadow', '0 0 5px 0px #eeeeee');
    },

    dropWrapLeave: function(event)
    {//鼠标离开展示区
        Z.E.forbidden(event);
        var $wrap = Z(Z.E.target(event));
        $wrap.css('box-shadow', '0 0 1px 0px transparent');
    },

    listItemEnter: function(event)
    {//鼠标进入列表文件（图片）
        var $item = Z(Z.E.target(event));
        $item.find('.Z-UploadLarge-image-wrap').css({
            '-webkit-filter': 'blur(6px)',
            '-moz-filter': 'blur(6px)',
            '-ms-filter': 'blur(6px)',
            'filter': 'blur(6px)',
        });
        $item.find('.Z-UploadLarge-details').show();
    },

    listItemLeave: function(event)
    {//鼠标移出列表文件（图片）
        var $item = Z(Z.E.target(event));
        $item.find('.Z-UploadLarge-image-wrap').css({
            '-webkit-filter': 'blur(0px)',
            '-moz-filter': 'blur(0px)',
            '-ms-filter': 'blur(0px)',
            'filter': 'blur(0px)',
        });
        $item.find('.Z-UploadLarge-details').hide();
    },

    dropWrapDrop: function(event)
    {//拖拽文件
        Z.E.forbidden(event);
        this.$file[0].value = null;
        this.files = event.dataTransfer.files;
        this.onFileListLoad();
    },

    onFileInputChange: function()
    {//选择文件
        this.files = this.$file[0].files;
        this.onFileListLoad();
    },

    onFileListLoad: function()
    {//确认文件
        this.filePreview = [];

        // 验证文件是否合法
        this.fileErrorTips = '';
        var flagMax = null;
        for (var i = 0;i < this.files.length;i++)
        {
            this.file = this.getFileObj(this.files[i]);
            if (!this.isFileRight())
                continue;
            if (this.multiSelect && this.maxFileNum && this.maxFileNum <= this.fileList.length + this.filePreview.length)
            {
                this.fileErrorTips = 'error';
                flagMax = true;
                break;
            }
            this.filePreview.push(this.file);
        }
        if (this.fileErrorTips)
        {
            if (this.multiSelect)
            {
                if (flagMax)
                    (top.Z || Z).alert('多文件上传数量限制为 ' + this.maxFileNum + ' 个！');
                else
                    (top.Z || Z).alert('包含不符合要求文件，已过滤！');
            } else
                (top.Z || Z).failure(this.fileErrorTips);
        }
        if (this.filePreview.length === 0)
            return;

        if (this.multiSelect)
        {//多文件上传模式
            if (this.runState === 2) {
                this.fileIndex = 0;
                this.fileBufferIndex = 0;
                this.fileList = [];
                this.fileResults = [];
                this.uploadedList = [];
                this.$dropWrap.find('.Z-UploadLarge-item').remove();
            }
            this.previewResults = [];
            this.runState = 0;
            this.showDropWrap();
            this.onFileLoad();
            return;
        }
        //单文件模式
        switch (this.displayType)
        {
            case 0:
            case 1:
                this.runState = 0;
                break;
            case 2:
                this.runState = 1;

                this.progressDialogShow();
                this.$progressTitle.html('正在加载').removeClass('zi-text-red zi-text-green').addClass('zi-text-black')
                    .parent().removeClass('zi-bg-red zi-bg-green').addClass('zi-bg-gray');
                this.$progressLoading.show();
                this.$progressWrap.find('.ZULPW-item').hide();

                if (/image\//.test(this.fileType))
                {
                    this.$ZULPW_viewType.html('');
                    var dataReader = new FileReader();
                    dataReader.onload = Z.bind(function(e){
                        this.$ZULPW_viewImg.attr('src', e.target.result);
                    }, this);
                    dataReader.readAsDataURL(this.file.file);
                }
                else
                {
                    this.$ZULPW_viewImg.attr('src', '');
                    this.$ZULPW_viewType.html(this.fileSuffix.toUpperCase());
                }
                break;
        }
        this.doUploadSingleFile();
    },

    getFileObj: function(fileData)
    {
        var newFile = {};
        newFile.lastModified = fileData.lastModified;
        newFile.lastModifiedDate = fileData.lastModifiedDate;
        newFile.name = fileData.name;
        newFile.size = fileData.size;
        newFile.type = fileData.type;
        newFile.webkitRelativePath = fileData.webkitRelativePath;
        newFile.file = fileData;
        return newFile;
    },

    isFileRight: function()
    {//检测文件是否正确
        this.fileName = this.getFileName(this.file.name);
        this.fileSize = this.file.size;
        this.fileType = this.file.type;
        var suffixArr = /\.([^.]+)$/.exec(this.fileName);
        this.fileSuffix = suffixArr[1] || 'FILE';

        if (Z.S.startWith(this.fileName, "\\."))
        {//选择的文件名不能点号开头，linux会认为是系统文件
            this.clear();
            this.fileErrorTips = "选择的文件名不能以[点号(.)]开头";
            return false;
        }

        if (this.fileSize <= 0)
        {//选择的文件不合法
            this.clear();
            this.fileErrorTips = "选择的文件无内容";
            return false;
        }

        if (this.maxSizeMiB > 0 && this.fileSize > this.maxSizeMiB*Z.UploadLarge.M)
        {
            this.fileErrorTips = "文件大小超过设定的["+this.maxSizeMiB+"M]";
            return false;
        }

        if (this.onSelected)
        {//回调文件已选中时对文件名称和大小进行检查
            var result = this.onSelected.call(this, this.fileName, this.fileSize);
            if (result === false)
            {
                if (!this.multiSelect)
                    this.clear();
                else
                    this.fileErrorTips = 'error';
                return;
            }
        }
        return true;
    },

    showDropWrap: function()
    {//显示多文件列表
        this.$dropWrap.show();
        var item = '';
        if (this.multiDisplayType === 0)
        {//0：默认的列表展示
            item +=
                '<div class="Z-UploadLarge-item z-h50 z-mg5 z-relative" style="font-weight:normal;font-size:14px;color:#333;padding-left:50px;padding-right:40px;background:#f1f1f1;">' +
                '<div class="Z-UploadLarge-image-wrap z-absolute z-overflow-hidden z-w40 z-h40" style="left:5px;top:5px;background:#fff;border:1px solid #ccc;border-radius:2px;">' +
                '<img class="Z-UploadLarge-image z-absolute z-mg-auto z-l0 z-t0 z-r0 z-b0">' +
                '<div class="Z-UploadLarge-image-text z-absolute z-px12 z-text-center z-bold z-color-999" style="width:35px;line-height:13px;top:50%;left:50%;transform:translate(-50%,-50%);display:none;"></div>' +
                '</div>' +
                '<div class="Z-UploadLarge-details z-relative z-h25 z-pd-t5">' +
                '<div class="Z-UploadLarge-name z-float-left z-px12 z-lh16 z-text-ellipsis" style="max-width:calc(100% - 85px);">' +
                '<span class="Z-UploadLarge-name-text z-show-ib"></span>' +
                '</div>' +
                '<div class="Z-UploadLarge-size z-float-left z-px12 z-pd-l5 z-text-ellipsis" style="width:85px;height:15px;border-radius:5px;">' +
                '<span class="z-show-ib">(<span class="Z-UploadLarge-size-text"><span class="z-bold z-mg-r3"></span><span></span></span>)</span>' +
                '</div>' +
                '</div>' +
                '<div class="Z-UploadLarge-progress-wrap z-relative z-h18 z-bd-rd2 z-text-center z-overflow-hidden z-bg-white z-bd" style="border:1px solid #ddd;">' +
                '<div class="Z-UploadLarge-progress-range z-absolute z-l0" style="top:-1px;bottom:-1px;background-color:#28a3ef;"></div>' +
                '<div class="Z-UploadLarge-progress-text z-absolute z-w100p z-px10 z-lh16" style="top:-1px;color:#777777;">文件加载中</div>' +
                '</div>' +
                '<a class="Z-UploadLarge-remove z-absolute z-px12 z-w40 z-h50 z-text-center z-lh50 z-t0 z-r0" href="javascript:;">取消</a>' +
                '<a class="Z-UploadLarge-delete z-absolute z-px12 z-w40 z-h50 z-text-center z-lh50 z-t0 z-r0 zi-hide z-text-green" href="javascript:;">删除</a>' +
                '<a class="Z-UploadLarge-done z-absolute z-px12 z-w40 z-h50 z-text-center z-lh50 z-t0 z-r0 zi-hide z-event-none z-text-green" href="javascript:;">完成</a>' +
                '<a class="Z-UploadLarge-error z-absolute z-px12 z-w40 z-h50 z-text-center z-lh50 z-t0 z-r0 zi-hide z-event-none z-text-orange" href="javascript:;"></a>' +
                '</div>';
        }
        else if (this.multiDisplayType === 1)
        {//1：图形块展示
            item +=
                '<div class="Z-UploadLarge-item z-mg16 z-relative z-show-ib z-text-center" style="font-weight:normal;font-size:14px;color:#333;">' +
                '<div class="Z-UploadLarge-image-wrap z-relative z-overflow-hidden z-w120 z-h120" style="border:1px solid #f1f1f1;border-radius:10px;background:#eee">' +
                '<img class="Z-UploadLarge-image z-absolute z-mg-auto z-l0 z-t0 z-r0" style="bottom:22px;">' +
                '<div class="Z-UploadLarge-image-text z-absolute z-t0 z-r0 z-b0 z-l0 z-px18 z-bold z-color-999" style="line-height:96px;display:none;">FILE</div>' +
                '</div>' +
                '<div class="Z-UploadLarge-details z-absolute z-l0 z-t0 z-r0 z-pd14" style="display:none;">' +
                '<div class="Z-UploadLarge-size z-lh15 zi-show-b z-text-ellipsis" style="border-radius:5px;">' +
                '<span class="Z-UploadLarge-size-text z-pd5 z-show-ib" style="border-radius:5px;background-color:rgba(255,255,255,.7);"><span class="z-bold z-mg-r5"></span><span></span></span>' +
                '</div>' +
                '<div class="Z-UploadLarge-name z-mg-t20 z-lh15 zi-show-b z-text-ellipsis" style="border-radius:5px;">' +
                '<span class="Z-UploadLarge-name-text z-pd5 z-show-ib" style="border-radius:5px;background-color:rgba(255,255,255,.7);"></span>' +
                '</div>' +
                '</div>' +
                '<div class="Z-UploadLarge-progress-wrap z-overflow-hidden z-absolute z-h22 z-bg-white" style="left:1px;right:1px;bottom:27px;border-bottom-left-radius:10px;border-bottom-right-radius:10px;">' +
                '<div class="Z-UploadLarge-progress-range z-absolute z-t0 z-b0 z-l0" style="background-color:#28a3ef"></div>' +
                '<div class="Z-UploadLarge-progress-text z-absolute z-w100p z-px12 z-lh22" style="color:#777777;">文件加载中</div>' +
                '</div>' +
                '<a class="Z-UploadLarge-remove z-show-ib z-mg-t10" href="javascript:undefined;">取消上传该文件</a>' +
                '<a class="Z-UploadLarge-delete z-show-ib z-mg-t10 zi-hide z-text-green" href="javascript:undefined;">删除已上传文件</a>' +
                '<a class="Z-UploadLarge-done z-show-ib z-mg-t10 zi-hide z-event-none z-text-green" href="javascript:undefined;">文件上传已完成</a>' +
                '<a class="Z-UploadLarge-error z-show-ib z-mg-t10 zi-hide z-event-none z-text-orange" href="javascript:undefined;"></a>' +
                '</div>';
        }

        //定义列表父节点
        var listParentId = 'Z-UploadLarge-multiList-' + this.random;
        var $listParent = this.$dropWrap.find('#' + listParentId);
        if (!$listParent[0])
        {
            var listParentStr = '<div id="'+listParentId+'" class="z-relative z-pd5" style="background-color: rgba(255,255,255,.7);"></div>';
            $listParent = Z(listParentStr);
            this.$dropWrap.append($listParent);
        }

        var i, theFile, $item;
        //插入列表
        for(i = 0;i < this.filePreview.length;i++)
        {
            theFile = this.filePreview[i];
            $item = Z(item);
            $listParent.append($item);

            //计算大小
            var size = theFile.size;
            var unit = 'Bytes';
            var $detail = $item.find('.Z-UploadLarge-details');
            var $size = $item.find('.Z-UploadLarge-size-text>span.z-bold');
            var $unit = $item.find('.Z-UploadLarge-size-text>span:last-child');
            var $name = $item.find('.Z-UploadLarge-name-text');
            if(!size || size <= 0){
                size = '0';
            } else {
                var unitArr = ["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"];
                var index = 0;
                index= Math.floor(Math.log(size) / Math.log(1024));
                size = parseFloat((size / Math.pow(1024,index)).toFixed(2));
                unit = unitArr[index];
            }
            $size.html(size);
            $unit.html(unit);
            $name.html(this.getFileName(theFile.name));

            // 区分图片 && 绑定事件
            if (/image\//.test(theFile.type))
            {
                $item.find('.Z-UploadLarge-progress-text').html('图片加载中');
                if (this.multiDisplayType === 1)
                {
                    $item.on('mouseenter', this.listItemEnter, this)
                        .on('mouseleave', this.listItemLeave, this);
                }
            } else if (this.multiDisplayType === 1) {
                $detail.show();
            }
            $item.find('.Z-UploadLarge-remove').on('click', this.remove, this);
            $item.find('.Z-UploadLarge-delete').on('click', this.delete, this);
        }
    },

    onFileLoad: function()
    {//加载多文件
        this.file = this.filePreview[this.previewResults.length];
        this.fileName = this.getFileName(this.file.name);
        this.fileSize = this.file.size;
        this.fileType = this.file.type;
        var suffixArr = /\.([^.]+)$/.exec(this.fileName);
        this.fileSuffix = suffixArr[1] || 'FILE';

        //所有文件
        this.fileList.push(this.file);

        //以文件字节计算MD5
        if (this.fileMd5Target === 1)
        {
            var bufferReader = new FileReader();
            bufferReader.onload = Z.bind(function(e)
            {
                this.fileResults.push(e.target.result);
                this.fileBufferIndex++;
            }, this);
            bufferReader.readAsArrayBuffer(this.file.file);
        }

        //图片预览
        if (/image\//.test(this.fileType))
        {
            var dataReader = new FileReader();
            dataReader.onload = Z.bind(function(e){
                this.addPreviewResults(e.target.result);
            }, this);
            dataReader.readAsDataURL(this.file.file);
        } else {
            this.addPreviewResults('');
        }
    },

    addPreviewResults: function (dataSrc)
    {//多文件预览信息
        this.previewResults.push({name: this.fileName, type: this.fileType, size: this.fileSize, suffix: this.fileSuffix, lastModified: this.file.lastModified, lastModifiedDate: this.file.lastModifiedDate, src: dataSrc});
        if (this.previewResults.length === this.filePreview.length)
            this.onPreview(this.previewResults);
        else
            this.onFileLoad();
    },

    onPreview: function()
    {//多文件（图片）预览
        var $$itemList = this.$dropWrap.find('.Z-UploadLarge-item');
        var indexStart = $$itemList.length - this.previewResults.length;
        var i, fileData, $item;
        for(i = 0;i < this.previewResults.length;i++)
        {
            fileData = this.previewResults[i];
            if (!fileData)
                continue;
            $item = Z($$itemList[indexStart + i]);

            $item.find('.Z-UploadLarge-progress-text').html('等待上传');
            if (/image\//.test(fileData.type)){
                $item.find('.Z-UploadLarge-image').attr('src', fileData.src);
            } else {
                $item.find('.Z-UploadLarge-image-text').html(fileData.suffix.toUpperCase()).show();
            }
        }
    },

    upload: function()
    {//执行多文件上传
        if (this.fileList.length === 0)
            return Z.alert('请先添加需要上传的文件！');
        if (this.runState === 2)
            return Z.alert('上传操作已完成，请重新添加文件！');
        if (this.runState === 1)
            return Z.alert('正在上传，请稍后...');
        if (!this.runState)
            this.runState = 1;

        //多文件，预读取过程
        if (this.fileMd5Target === 1 && this.fileBufferIndex !== this.fileList.length)
        {
            this.checkInterval = setInterval(this.checkFileResults.apply(this), 100);
            return;
        }

        if (this.checkInterval)
            this.checkInterval.clearInterval();
        //执行上传
        this.doUpload();
    },

    checkFileResults: function()
    {//文件加载是否完成
        if (this.fileBufferIndex === this.fileList.length){
            this.loading.close();
            this.runState = 0;
            return this.upload();
        }

        if (!this.loading){
            this.loading = Z.loading({text: "准备上传...",target: this.$dropWrap[0].id, shadow: true});
            this.loading.$shadow.css({'top': 0});
        }
    },

    doUpload: function()
    {//按队列执行上传
        if (this.fileIndex === 0){
            this.$dropWrap.find('.Z-UploadLarge-progress-wrap').show();
        }
        if (this.fileIndex >= this.fileList.length){
            return this.done();
        }
        this.file = this.fileList[this.fileIndex];
        this.fileName = this.getFileName(this.file.name);
        this.fileSize = this.file.size;
        this.fileType = this.file.type;

        var $theItem = Z(this.$dropWrap.find('.Z-UploadLarge-item')[this.fileIndex]);
        $theItem.find('.Z-UploadLarge-progress-text').html('正在上传');
        this.doUploadSingleFile();
    },

    doUploadSingleFile: function()
    {//上传（单文件）
        this.chunkNum = Math.floor((this.fileSize - 1) / Z.UploadLarge.CHUNK_SIZE) + 1;
        this.chunkNo = 1;

        if (!Z.V.isIntegerValue(this.fileMd5Target, 0, 2))
        {//MD5目标，仅支持0,1,2，0表示使用UUID进行MD5，1表示文件bytes进行MD5，2表示文件名进行MD5
            this.fileMd5Target = 0;
        }

        switch(this.fileMd5Target)
        {
            case 0:
            {//以UUID为目标进行MD5算法，则不需要加载即上传
                this.fileMd5 = Z.MD5.encode(Z.uuid());
                this.runState = 1;
                this.time = new Date().getTime();
                this.doUploadChunk();
                break;
            }
            case 1:
            {//加载完字节后计算MD5，再上传
                if (this.multiSelect)
                {
                    var fileResult = this.fileResults[this.fileIndex];
                    var bytes = new Int8Array(fileResult);
                    this.fileMd5 = Z.MD5.encode(bytes);
                    this.runState = 1;
                    this.time = new Date().getTime();
                    this.doUploadChunk();
                    break;
                }
                //大于指定M的文件增加loading
                if (this.fileSize > this.maxLoadingMiB * Z.UploadLarge.M)
                {
                    switch (this.displayType)
                    {
                        case 0:
                        case 1:
                            this.loading = Z.loading({text: "文件解析中...", shadow: true, width: 160});
                            break;
                        case 2:
                            break;
                    }
                }
                var reader = new FileReader();
                reader.onload = Z.bind(function(event)
                {
                    if (event.target.readyState !== FileReader.DONE)
                        return;
                    if (this.loading)
                        this.loading.close();
                    var bytes = new Int8Array(event.target.result);
                    this.fileMd5 = Z.MD5.encode(bytes);
                    this.runState = 1;
                    this.time = new Date().getTime();
                    this.doUploadChunk();
                }, this);
                reader.readAsArrayBuffer(this.file.file);
                break;
            }
            case 2:
            {//以文件名为目标进行MD5算法，则不需要加载即上传
                this.fileMd5 = Z.MD5.encode(this.fileName);
                this.runState = 1;
                this.time = new Date().getTime();
                this.doUploadChunk();
                break;
            }
        }
    },

    doUploadChunk: function()
    {//上传分块
        if (!this.runState || this.chunkNum < this.chunkNo)
            return this.onUploadError();

        // 校验上传过程中，文件是否进行了修改，依 size 判断
        var fileLoc = this.file.file;
        if (this.fileSize !== fileLoc.size)
            return this.onUploadError('文件上传过程已修改，取消上传！');

        var chunk;
        if (this.chunkNo === this.chunkNum)
            chunk = fileLoc.slice((this.chunkNo-1)*Z.UploadLarge.CHUNK_SIZE);
        else
            chunk = fileLoc.slice((this.chunkNo-1)*Z.UploadLarge.CHUNK_SIZE, this.chunkNo*Z.UploadLarge.CHUNK_SIZE);

        if (Z.B.mobile)
        {//移端端要改为ArrayBuffer（默认使用Int8Array）
            var reader = new FileReader();
            reader.onload = Z.bind(function(event)
            {
                if (event.target.readyState !== FileReader.DONE)
                    return;
                var chunk = new Int8Array(event.target.result);
                this.doUploadChunkSend(chunk);
            }, this);
            reader.readAsArrayBuffer(chunk);
        }
        else
        {//电脑端支持发送Blob对象（即File类型）
            this.doUploadChunkSend(chunk);
        }
    },

    doUploadChunkSend: function(chunk)
    {
        this.request = new XMLHttpRequest();
        this.request.open("POST", Z.rootPath(this.contextPath, "/service/uploadlarge"), true);
        this.request.setRequestHeader("Content-Type", this.fileType);
        if (this.fileDir)
            this.request.setRequestHeader("X-Upload-File-Dir", encodeURIComponent(this.fileDir));
        this.request.setRequestHeader("X-Upload-File-Name", encodeURIComponent(this.fileName));
        this.request.setRequestHeader("X-Upload-File-Md5", this.fileMd5);
        this.request.setRequestHeader("X-Upload-File-Md5-Target", this.fileMd5Target);
        this.request.setRequestHeader("X-Upload-File-Copy", this.fileCopy?1:0);
        this.request.setRequestHeader("X-Upload-File-Length", ""+this.fileSize);
        this.request.setRequestHeader("X-Upload-Chunk-Size", ""+Z.UploadLarge.CHUNK_SIZE);
        this.request.setRequestHeader("X-Upload-Chunk-Num", ""+this.chunkNum);
        this.request.setRequestHeader("X-Upload-Chunk-No", ""+this.chunkNo);
        if (this.headerList && this.headerList.length) {
            for (var headObj of this.headerList) {
                this.request.setRequestHeader(headObj.name, headObj.value);
            }
        }
        this.request.onreadystatechange = Z.bind(this.onUploadSuccess, this);
        this.request.onerror = Z.bind(function(){this.onUploadError("文件上传连接服务器失败")}, this);
        this.request.send(chunk);
    },

    onUploadError: function(errorText)
    {
        // 重新上传，次数判断
        if (this.reConnectTimes > 0)
        {
            this.reConnectTimes--;
            this.doUploadChunk();
            return;
        }

        // 上传类型判断
        if (this.multiSelect)
        {
            var $theItem = Z(this.$dropWrap.find('.Z-UploadLarge-item')[this.fileIndex]);
            var pText = '失败';
            var eText = '文件上传失败';
            if(this.multiDisplayType === 1) {
                pText = '文件上传失败';
                eText = '上传失败';
            }

            var $range = $theItem.find('.Z-UploadLarge-progress-range');
            var $text = $theItem.find('.Z-UploadLarge-progress-text');
            $range.css('backgroundColor', '#d33');
            $text.html(eText).css('color', '#d33');
            var widthPercent = $range[0].offsetWidth / $theItem.find('.Z-UploadLarge-progress-wrap')[0].offsetWidth;
            if (widthPercent > .5)
                $text.css('color', '#FFFFFF');

            $theItem.find('.Z-UploadLarge-remove').addClass('zi-hide');
            $theItem.find('.Z-UploadLarge-error').removeClass('zi-hide').html(pText);
            this.runState = 1;
            this.fileIndex++;
            this.doUpload();
            return;
        }
        switch (this.displayType)
        {
            case 0:
                this.clear();
                if (errorText)
                    (top.Z || Z).failure(errorText);
                break;
            case 1:
                this.clear();
                this.$elem.visible();
                this.$progressRange.css({'backgroundColor': '#ff6600'});
                this.$progressText.html('错误');

                errorText = errorText || '文件上传失败！';
                (top.Z || Z).failure(errorText);
                break;
            case 2:
                this.$progressTitle.html('上传失败').removeClass('zi-text-black zi-text-green').addClass('zi-text-red')
                    .parent().removeClass('zi-bg-gray zi-bg-green').addClass('zi-bg-red');
                this.$ZULPW_range.css('backgroundColor', '#ff6600');
                this.$ZULPW_speed.html('---');
                this.$ZULPW_time.html('---');

                if (errorText)
                    (top.Z || Z).failure(errorText);
                break;
            default:
                if (errorText)
                    (top.Z || Z).failure(errorText);
                break;
        }
    },

    completeSingleFile: function(all, fileId, fileName, fileUrl, filePath)
    {//上传单个文件完成
        if (this.multiSelect)
        {//多文件上传，队列上传
            var $theItem = Z(this.$dropWrap.find('.Z-UploadLarge-item')[this.fileIndex]);
            $theItem.find('.Z-UploadLarge-progress-text').css('color', '#FFFFFF');
            $theItem.find('.Z-UploadLarge-remove').addClass('zi-hide');

            if (this.deleteFile) {
                $theItem.find('.Z-UploadLarge-delete').removeClass('zi-hide');
            } else {
                $theItem.find('.Z-UploadLarge-done').removeClass('zi-hide');
            }

            var doneText = '上传完成';
            if (this.multiDisplayType === 0)
                doneText += ' 100%';
            $theItem.find('.Z-UploadLarge-progress-text').html(doneText);
            $theItem.find('.Z-UploadLarge-progress-range').css('width', '100%');

            this.uploadedList.push({
                'fileId': fileId,
                'fileName': fileName,
                'fileUrl': fileUrl,
                'filePath': filePath
            });
            Z.T.isFunction(this.onCompletedForEach) && this.onCompletedForEach.call(this, fileId, fileName, fileUrl, $theItem);

            this.fileIndex++;
            this.doUpload();
            return;
        }
        //单文件上传结束
        this.clear();

        var left = this.$elem.offsetLeft();
        var top = this.$elem.offsetTop();
        switch (this.displayType)
        {
            case 0:
                this.$elem.hidden();
                this.$progress.hide();
                Z("#Z_UploadLarge_result_fileName_"+this.random).html(fileName);
                if (this.showResult)
                {//显示结果
                    this.$result.css({top: top, left: left});
                    this.$result.show();
                }
                else
                {//返回上传按钮
                    this.$elem.visible();
                }
                break;
            case 1:
                this.$progress.css({top: top, left: left}).show();
                this.$elem.visible();
                this.$progress.find('.Z-UploadLarge-progress-range').css('width', '100%');
                this.$progress.find('.Z-UploadLarge-progress-text').html('已上传').css('color', '#FFFFFF');
                (top.Z || Z).tips({text: '上传完成', timeout: 2000});
                break;
            case 2:
                this.$progressTitle.html('上传完成').removeClass('zi-text-black zi-text-red').addClass('zi-text-green')
                    .parent().removeClass('zi-bg-gray zi-bg-red').addClass('zi-bg-green');
                this.$progressLoading.hide();
                this.$progress.show();

                this.$ZULPW_name.html(fileName);
                this.$ZULPW_size.html(all);
                this.$ZULPW_range.css("width", "100%");
                this.$ZULPW_uploaded.html(all);
                if (Z.V.isEmpty(this.$ZULPW_speed.html()))
                    this.$ZULPW_speed.html('---');
                this.$ZULPW_time.html('---');
                this.$ZULPW_cancel.removeClass('z-red z-error').addClass('z-green z-success z-event-none');
                setTimeout(this.progressDialogHide, 3000, this);
                break;
        }
        // 但文件上传完成，成功回调方法
        Z.T.isFunction(this.onCompleted) && this.onCompleted.call(this, fileId, fileName, fileUrl, filePath);
    },

    onUploadSuccess: function()
    {
        if (this.request.readyState !== 4)
        {//readyState != 4表示未就绪
            return;
        }
        if (this.request.status === 0)
        {//status == 0表示进入onUploadError
            this.onUploadError();
            return;
        }

        switch(this.request.status)
        {
            case 404:this.onUploadError("文件上传时服务器不支持");return;
            case 403:this.onUploadError("文件上传时被服务器拒绝");return;
            case 412:this.onUploadError("文件上传时服务器诊断参数格式错误");return;
            case 413:this.onUploadError("文件上传时客户端不支持分块上传");return;
            case 415:this.onUploadError("文件上传时客户端分块上传出错，请重传");return;
            case 400:this.onUploadError("文件上传时服务器诊断参数传值错误");return;
            case 200:
            {
                var fileId = this.request.getResponseHeader("X-Upload-File-Id");
                var currentNo = this.request.getResponseHeader("X-Upload-Chunk-No");
                if (!fileId && !currentNo)
                {//不确定的服务器异常
                    this.onUploadError("文件上传时服务器异常");
                }

                var all = Math.round(this.fileSize / Z.UploadLarge.M * 100) / 100;

                if (fileId)
                {//秒传和上传完成
                    var fileUrl = this.request.getResponseHeader("X-Upload-File-Url");
                    var fileName = this.request.getResponseHeader("X-Upload-File-Name");
                    var filePath = this.request.getResponseHeader("X-Upload-File-Path");
                    
                    if (fileName != null)
                        fileName = decodeURIComponent(fileName);
                    else
                        fileName = this.fileName;
                    this.completeSingleFile(all, fileId, fileName, fileUrl, filePath);
                    return;
                }

                if (this.runState === 0)
                {//被取消
                    this.onUploadError();
                    return;
                }

                //续传和上传碎片
                this.chunkNo = parseInt(currentNo);
                var percent = Math.floor(100*this.chunkNo/this.chunkNum);
                var already = this.chunkNo * Z.UploadLarge.CHUNK_SIZE;
                var alr = Math.round(already / Z.UploadLarge.M * 100) / 100;
                var diff = (new Date().getTime() - this.time) / 1000;
                var speed = already / diff / 1024;
                var remain = Math.round((diff / this.chunkNo) * (this.chunkNum - this.chunkNo));
                //console.info(diff + "," + remain);

                if (speed < 1024)
                    speed = Math.round(speed * 100) / 100 + "K/s";
                else
                    speed = Math.round(speed / 1024 * 100) / 100 +"M/s";

                if (remain < 60)
                    remain = remain + "秒";
                else
                    remain = Math.floor(remain/60) + "分钟" + (remain % 60) + "秒";

                this.progress(this.fileName, percent, all, alr, speed, remain);
                this.chunkNo++;
                this.doUploadChunk();
                return;
            }
            case 799:this.onUploadError(this.request.responseText);return;
            default:this.onUploadError("文件上传时服务器未知错误："+this.request.status);return;
        }
    },

    progress: function(fileName, percent, all, alr, speed, remain)
    {//上传进度

        var rangeText = percent + '%';
        var $progressText = null;  
        //多文件上传进度
        if (this.multiSelect)
        {
            if (!this.$dropWrap || !this.fileIndex)
                return;
            var $theItem = Z(this.$dropWrap.find('.Z-UploadLarge-item')[this.fileIndex]);
            $theItem.find('.Z-UploadLarge-progress-wrap').show();
            $theItem.find('.Z-UploadLarge-progress-range').css('width', percent + '%');

            if (this.multiDisplayType === 0)
                rangeText = '正在上传 ' + rangeText;
            $progressText = $theItem.find('.Z-UploadLarge-progress-text');
            $progressText.html(rangeText);
            $progressText.css('color', percent > 50 ? '#FFFFFF' : '#777777');
            return;
        }
        //单文件上传进度条
        if (!this.$elem || !this.$progress)
            return;

        var left = this.$elem.offsetLeft();
        var top = this.$elem.offsetTop();
        switch (this.displayType)
        {
            case 0:
                this.$elem.hidden();
                this.$progress.css({top: top, left: left}).show();
                this.$result.hide();
                Z("#Z_UploadLarge_fileName_"+this.random).html(fileName);
                Z("#Z_UploadLarge_all_"+this.random).html(all);
                Z("#Z_UploadLarge_percent_"+this.random).css("width", percent+"%");
                Z("#Z_UploadLarge_already_"+this.random).html(alr);
                Z("#Z_UploadLarge_speed_"+this.random).html(speed);
                Z("#Z_UploadLarge_remain_"+this.random).html(remain);
                break;
            case 1:
                this.$elem.hidden();
                this.$progress.css({top: top, left: left}).show();
                this.$progressRange.css(
                    {
                        'width': percent + '%',
                        'backgroundColor': '#28a3ef',
                    });
                this.$progressText.html(rangeText);
                this.$progressText.css('color', percent > 50 ? '#FFFFFF' : '#777777');
                break;
            case 2:
                this.$progressTitle.html('正在上传').removeClass('zi-text-red zi-text-green').addClass('zi-text-black')
                    .parent().removeClass('zi-bg-red zi-bg-green').addClass('zi-bg-gray');
                this.$progressLoading.hide();
                this.$progress.show();

                this.$ZULPW_name.html(fileName);
                this.$ZULPW_size.html(all);
                this.$ZULPW_range.css("width", percent+"%");
                this.$ZULPW_uploaded.html(alr);
                this.$ZULPW_speed.html(speed);
                this.$ZULPW_time.html(remain);
                this.$ZULPW_cancel.removeClass('z-green z-success z-event-none').addClass('z-red z-error');
                break;
        }
    },

    cancel: function()
    {
        this.$elem.visible();
        this.$progress.hide();
        this.$result.hide();
        this.clear();
    },

    progressDialogShow: function()
    {
        this.$progressWrap.css(
            {
                'bottom': '10px',
                'transition': 'bottom 0s',
                '-moz-transition': 'bottom 0s',
                '-webkit-transition': 'bottom 0s',
            });
    },

    progressDialogHide: function(obj)
    {
        var $progressWrap = obj && obj.$progressWrap;
        $progressWrap = $progressWrap || this.$progressWrap;
        if (!$progressWrap[0])
            return;
        $progressWrap.css(
            {
                'bottom': '-120px',
                'transition': 'bottom 1s',
                '-moz-transition': 'bottom 1s',
                '-webkit-transition': 'bottom 1s',
            });
    },

    remove: function(event)
    {
        Z.E.forbidden(event);
        var $item = Z(event.currentTarget.parentNode);
        var $$item = this.$dropWrap.find('.Z-UploadLarge-item');
        var itemIndex = [].indexOf.call($$item, $item[0]);
        if (this.runState === 0 || itemIndex > this.fileIndex)
        {
            this.fileList.splice(itemIndex, 1);
            this.fileResults.splice(itemIndex, 1);
            this.fileBufferIndex--;
            $item.remove();
        } else {
            this.runState = 0;
        }
        !this.dropWrap && !this.$dropWrap.find(".Z-UploadLarge-item")[0] && this.$dropWrap.hide();
    },

    delete: function(event)
    {
        Z.E.forbidden(event);
        var $item = Z(event.currentTarget.parentNode);
        var $$item = this.$dropWrap.find('.Z-UploadLarge-item');
        var itemIndex = [].indexOf.call($$item, $item[0]);
        var fileObj = this.uploadedList[itemIndex];

        $item.remove();
        !this.dropWrap && !this.$dropWrap.find(".Z-UploadLarge-item")[0] && this.$dropWrap.hide();
        this.deleteFile && this.doFileDelete.call(this, fileObj.fileId, fileObj.fileName, fileObj.fileUrl);
    },

    done: function()
    {
        this.clear();
        this.runState = 2;
        Z.T.isFunction(this.onCompleted) && this.onCompleted.call(this, this.fileList, this.uploadedList);
    },

    clear: function()
    {
        this.runState = 0;
        if (this.$file && this.$file[0])
            this.$file[0].value = null;
        this.file = null;
        this.fileName = null;
        this.fileMd5 = null;
        this.chunkNum = 0;
        this.chunkNo = 0;
    },

    /***********************************************************************************/
    //设置方法
    /***********************************************************************************/

    setFileFormatDesc: function(fileFormatDesc)
    {
        this.fileFormatDesc = fileFormatDesc;
        return this;
    },

    setFileFormatExt: function(fileFormatExt)
    {
        this.fileFormatExt = fileFormatExt;
        return this;
    },

    setFileMd5Target: function(target)
    {
        this.fileMd5Target = target;
        return this;
    },

    setFileDir: function(fileDir)
    {
        this.fileDir = fileDir;
        return this;
    },

    setHeaderList: function(headerList)
    {
        this.headerList = headerList;
        return this;
    },
            
    setFileName: function(fileName)
    {
        if (this.multiSelect && this.file)
            this.file.name = fileName;
        else
            this.fileName = fileName;
        return this;
    },

    getFileName: function(filePath)
    {
        var ind = filePath.lastIndexOf("\\");
        if (ind != -1)
            return filePath.substring(ind + 1);

        ind = filePath.lastIndexOf("/");
        if (ind != -1)
            return filePath.substring(ind + 1);

        return filePath;
    }
};

//END
})(zhiqim);